﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Printing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace FastReport
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            ////打印清单
            //DataTable dt = new DataTable("Items");
            ////1.创建空列

            //DataColumn dc = new DataColumn();

            ////2.创建带列名和类型名的列(两种方式任选其一)

            //dt.Columns.Add("XINGMING", System.Type.GetType("System.String"));

            //dt.Columns.Add("SN", System.Type.GetType("System.String"));

            //dt.Columns.Add(dc);
            ////1.创建空行

            //DataRow dr = dt.NewRow();
            //dt.Rows.Add(dr);
            ////2.创建空行
            //dt.Rows.Add();
            ////3.通过行框架创建并赋值
            //dt.Rows.Add("75HHHHHJKK", DateTime.Now);

            //ReportViewer rvDoc = new ReportViewer();
            //rvDoc.LocalReport.ReportEmbeddedResource = System.Windows.Forms.Application.StartupPath + "\\" + "SXBOX_TVS.rdlc";// "SD_bcso.Report.rdlc";//加上报表的路径
            //                                                                                                                  // rvDoc.LocalReport.DataSources.Add(new ReportDataSource(dt.TableName, dt));


            ////string a = "测试";
            //ReportParameter rp = new ReportParameter("XINGMING", "12344444");
            //ReportParameter nn = new ReportParameter("SN", "ABCDEFG");
            //rvDoc.LocalReport.SetParameters(new ReportParameter[] { rp, nn });
            //rvDoc.RefreshReport();


            //PrintStream(rvDoc.LocalReport);
        }

        private void loadprint()
        {
            PrintDocument prtdoc = new PrintDocument();
            string strDefaultPrinter = prtdoc.PrinterSettings.PrinterName;//获取默认的打印机名
            foreach (string ss in PrinterSettings.InstalledPrinters)
            {
                ///在列表框中列出所有的打印机,
                this.comboBox1.Items.Add(ss);
                if (ss == strDefaultPrinter)//把默认打印机设为缺省值
                {
                    comboBox1.SelectedIndex = comboBox1.Items.IndexOf(ss);
                }
            }
        }
        /// <summary>
        /// 用来记录当前打印到第几页了
        /// </summary>
        private int m_currentPageIndex;

        /// <summary>
        /// 声明一个Stream对象的列表用来保存报表的输出数据,LocalReport对象的Render方法会将报表按页输出为多个Stream对象。
        /// </summary>
        private IList<Stream> m_streams;

        private bool isLandSapces = false;

        /// <summary>
        /// 用来提供Stream对象的函数，用于LocalReport对象的Render方法的第三个参数。
        /// </summary>
        /// <param name="name"></param>
        /// <param name="fileNameExtension"></param>
        /// <param name="encoding"></param>
        /// <param name="mimeType"></param>
        /// <param name="willSeek"></param>
        /// <returns></returns>
        private Stream CreateStream(string name, string fileNameExtension, Encoding encoding, string mimeType, bool willSeek)
        {
            //如果需要将报表输出的数据保存为文件，请使用FileStream对象。
            Stream stream = new MemoryStream();
            m_streams.Add(stream);
            return stream;
        }

        ///// <summary>
        ///// 为Report.rdlc创建本地报告加载数据,输出报告到.emf文件,并打印,同时释放资源
        ///// </summary>
        ///// <param name="rv">参数:ReportViewer.LocalReport</param>
        //public void PrintStream(LocalReport rvDoc)
        //{
        //    //获取LocalReport中的报表页面方向
        // //   isLandSapces = rvDoc.GetDefaultPageSettings().IsLandscape;
        //    Export(rvDoc);
        //    PrintSetting();
        //    Dispose();
        //}

        //private void Export(LocalReport report)
        //{
        //    string deviceInfo =
        //    @"<DeviceInfo>
        //         <OutputFormat>EMF</OutputFormat>
        //     </DeviceInfo>";
        //    Warning[] warnings;
        //    m_streams = new List<Stream>();
        //    //将报表的内容按照deviceInfo指定的格式输出到CreateStream函数提供的Stream中。
        //    report.Render("Image", deviceInfo, CreateStream, out warnings);
        //    foreach (Stream stream in m_streams)
        //        stream.Position = 0;
        //}

        private void PrintSetting()
        {
            if (m_streams == null || m_streams.Count == 0)
                throw new Exception("错误:没有检测到打印数据流");
            //声明PrintDocument对象用于数据的打印
            PrintDocument printDoc = new PrintDocument();
            //获取配置文件的清单打印机名称
            System.Configuration.AppSettingsReader appSettings = new System.Configuration.AppSettingsReader();
            printDoc.PrinterSettings.PrinterName = comboBox1.SelectedItem.ToString();

            // appSettings.GetValue("QDPrint", Type.GetType("System.String")).ToString();
            printDoc.PrintController = new System.Drawing.Printing.StandardPrintController();//指定打印机不显示页码 
            //判断指定的打印机是否可用
            if (!printDoc.PrinterSettings.IsValid)
            {
                throw new Exception("错误:找不到打印机");
            }
            else
            {
                //设置打印机方向遵从报表方向
                printDoc.DefaultPageSettings.Landscape = isLandSapces;
                //声明PrintDocument对象的PrintPage事件，具体的打印操作需要在这个事件中处理。
                printDoc.PrintPage += new PrintPageEventHandler(PrintPage);
                m_currentPageIndex = 0;
                //设置打印机打印份数
                printDoc.PrinterSettings.Copies = 1;
                //执行打印操作，Print方法将触发PrintPage事件。
                printDoc.Print();
            }
        }

        /// <summary>
        /// 处理程序PrintPageEvents
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="ev"></param>
        private void PrintPage(object sender, PrintPageEventArgs ev)
        {
            //Metafile对象用来保存EMF或WMF格式的图形，
            //我们在前面将报表的内容输出为EMF图形格式的数据流。
            Metafile pageImage = new Metafile(m_streams[m_currentPageIndex]);

            //调整打印机区域的边距
            System.Drawing.Rectangle adjustedRect = new System.Drawing.Rectangle(
                ev.PageBounds.Left - (int)ev.PageSettings.HardMarginX,
                ev.PageBounds.Top - (int)ev.PageSettings.HardMarginY,
                ev.PageBounds.Width,
                ev.PageBounds.Height);

            //绘制一个白色背景的报告
            //ev.Graphics.FillRectangle(Brushes.White, adjustedRect);

            //获取报告内容
            //这里的Graphics对象实际指向了打印机
            ev.Graphics.DrawImage(pageImage, adjustedRect);
            //ev.Graphics.DrawImage(pageImage, ev.PageBounds);

            // 准备下一个页,已确定操作尚未结束
            m_currentPageIndex++;

            //设置是否需要继续打印
            ev.HasMorePages = (m_currentPageIndex < m_streams.Count);
        }

        public void Dispose()
        {
            if (m_streams != null)
            {
                foreach (Stream stream in m_streams)
                    stream.Close();
                m_streams = null;
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            loadprint();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            FastReport.Report ms_report = new FastReport.Report();
            ms_report.Design();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            DataTable dataTable2 = new DataTable("FJD");
            dataTable2.Columns.Add("SN");
            dataTable2.Columns.Add("NAME");
            dataTable2.Columns.Add("MODEL");
             dataTable2.Columns.Add("WEIGHT");
            dataTable2.Columns.Add("COUNT");
            dataTable2.Columns.Add("JZ");
            var row = dataTable2.NewRow();
            row.SetField("SN", "12345-12345-12345-10001");
            row.SetField("NAME", "附件袋组件");
            row.SetField("MODEL", "G2225EK");
            row.SetField("WEIGHT", "11.875"+"KG");
            row.SetField("COUNT", "10001");
            row.SetField("JZ", "净重:");//这个写死
            dataTable2.Rows.Add(row);

            PrintHelper.Print("SX_FJD_PKG", null, dataTable2, 2, comboBox1.SelectedItem.ToString());
        }
    }


    public class PrintHelper
    {
        #region --获取打印基目录--
        public static string GetBarFile(string Folder, string file)
        {
            string str_file = AppDomain.CurrentDomain.BaseDirectory + Folder + @"\" + file;
            return str_file;
        }
        #endregion

        /// <summary>
        /// 打印
        /// </summary>
        /// <param name="fileName">文件名</param>
        /// <param name="listValue">泛型，string取模板中的参数名 ，object为参数所要获得的值</param>
        ///  <param name="dt">数据源</param>
        ///  <param name="flag">0 设计，1预览，2直接打印</param>
        public static void Print(string fileName, Dictionary<string, object> listValue, DataTable dt, int flag, string PrinterName)
        {
            FastReport.Report ms_report = new FastReport.Report();
            try
            {
                ms_report.Load(AppDomain.CurrentDomain.BaseDirectory + "LaberTemplate" + @"\" + fileName + ".frx");//获取打印文件，module 为保存打印文件的文件夹名称
            }
            catch
            {
                throw new System.ArgumentException(fileName + ".frx不存在或者加载失败！");
            }

            if (null != dt && dt.Rows.Count > 0)
            {
                string tn = dt.TableName;
                DataSet ds = new DataSet();
                ds.Tables.Add(dt.Copy());
                ms_report.RegisterData(ds);//注册数据源
            }

            if (listValue != null)
            {
                foreach (string str in listValue.Keys)
                {
                    ms_report.SetParameterValue(str, listValue[str]); ;//给模板中参数Pcode赋值
                }
            }

            ms_report.PrintSettings.ShowDialog = false;
            if (!string.IsNullOrEmpty(PrinterName))
            {
                ms_report.PrintSettings.Printer = PrinterName;
            }
            ms_report.Print();
        }
     

    }
}
